/*
 * File:        UDP_Parser.h
 * Authors:     Shaan Mulchandani (ee122-bv) and  Jonathan Kotker (ee122-bw)
 * Description: This header file contains the methods required to parse
 *              a UDP message received from the network.
 */

#ifndef _UDP_PARSER_H
#define	_UDP_PARSER_H

#define MIN(a, b) ((a) > (b) ? (b) : (a))
#define MAX(a, b) ((a) < (b) ? (b) : (a))

#include "constants.h"
#include "UDP_Contents.h"
#include "stringUtils.h"

#include <stdlib.h>
#include <sys/socket.h>

void set_player_name(char* packetBytes,
        UDP_Contents* content, int min, int max) {
    setString(content->playerName, packetBytes, min, max);
    content->playerName[EE122_MAX_NAME_LENGTH] = 0;
};

unsigned long int get_hp_exp_id(char* packetbytes, int x) {
    return ntohl(*((unsigned long int *)(packetbytes + x)));
};

unsigned short int get_ports(char* packetbytes, int x) {
    return ntohs(*((unsigned short int *)(packetbytes + x)));
};

void parseUdpPacket(char packetbytes[], UDP_Contents* content) {

    content->errorFlag = 0;

    content->messageType = packetbytes[0];

    if ((content->messageType < 0x00) || (content->messageType > 0x07))
        content->errorFlag = 1;

    switch (content->messageType) {
        case STORAGE_LOCATION_REQUEST:{
            content->id = get_hp_exp_id(packetbytes, 1);
            if (content->id < 0)
                content->errorFlag = 1;
            set_player_name(packetbytes, content, 5, 15);
            break;
        }

        // CHECK PORT
        case STORAGE_LOCATION_RESPONSE: {
            content->id = get_hp_exp_id(packetbytes, 1);
            if (content->id < 0)
                content->errorFlag = 1;
            content->server_ip_add = get_hp_exp_id(packetbytes, 5);
            if (content->server_ip_add < 0)
                content->errorFlag = 1;
            content->server_udp_port = get_ports(packetbytes, 9);
            break;
        }

        case SERVER_AREA_REQUEST: {
            content->id = get_hp_exp_id(packetbytes, 1);
            if (content->id < 0)
                content->errorFlag = 1;
            content->xLoc = packetbytes[5];
            if ((content->xLoc < 0) || (content->xLoc > 99))
                content->errorFlag = 1;
            content->yLoc = packetbytes[6];
            if ((content->yLoc < 0) || (content->yLoc > 99))
                content->errorFlag = 1;
            break;
        }

        case SERVER_AREA_RESPONSE: {
            content->id = get_hp_exp_id(packetbytes, 1);
            if (content->id < 0)
                content->errorFlag = 1;
            content->server_ip_add = get_hp_exp_id(packetbytes, 5);
            if (content->server_ip_add < 0)
                content->errorFlag = 1;
            content->server_tcp_port = get_ports(packetbytes, 9);
            content->minX = packetbytes[11];
            if ((content->minX < 0) || (content->minX > 99))
                content->errorFlag = 1;
            content->maxX = packetbytes[12];
            if ((content->maxX < 0) || (content->maxX > 99))
                content->errorFlag = 1;
            content->minY = packetbytes[13];
            if ((content->minY < 0) || (content->minY > 99))
                content->errorFlag = 1;
            content->maxY = packetbytes[14];
            if ((content->maxY < 0) || (content->maxY > 99))
                content->errorFlag = 1;
            break;
        }

        case PLAYER_STATE_REQUEST: {
            content->id = get_hp_exp_id(packetbytes, 1);
            if (content->id < 0)
                content->errorFlag = 1;
            set_player_name(packetbytes, content, 5, 15);
            break;
        }

        case PLAYER_STATE_RESPONSE: {
            content->id = get_hp_exp_id(packetbytes, 1);
            if (content->id < 0)
                content->errorFlag = 1;
            set_player_name(packetbytes, content, 5, 15);
            content->hp = get_hp_exp_id(packetbytes, 15);
            if (content->hp < 0)
                content->errorFlag = 1;
            content->exp = get_hp_exp_id(packetbytes, 19);
            if (content->exp < 0)
                content->errorFlag = 1;
            content->xLoc = packetbytes[23];
            if ((content->xLoc < 0) || (content->xLoc > 99))
                content->errorFlag = 1;
            content->yLoc = packetbytes[24];
            if ((content->yLoc < 0) || (content->yLoc > 99))
                content->errorFlag = 1;
            break;
        }

        case SAVE_STATE_REQUEST: {
            content->id = get_hp_exp_id(packetbytes, 1);
            if (content->id < 0)
                content->errorFlag = 1;
            set_player_name(packetbytes, content, 5, 15);
            content->hp = get_hp_exp_id(packetbytes, 15);
            if (content->hp < 0)
                content->errorFlag = 1;
            content->exp = get_hp_exp_id(packetbytes, 19);
            if (content->exp < 0)
                content->errorFlag = 1;
            content->xLoc = packetbytes[23];
            if ((content->xLoc < 0) || (content->xLoc > 99))
                content->errorFlag = 1;
            content->yLoc = packetbytes[24];
            if ((content->yLoc < 0) || (content->yLoc > 99))
                content->errorFlag = 1;
            break;
        }

        case SAVE_STATE_RESPONSE: {
           content->id = get_hp_exp_id(packetbytes, 1);
           if (content->id < 0)
                content->errorFlag = 1;
           content->errorCode = packetbytes[5];
           if ((content->errorCode != 0) && (content->errorCode != 1))
                content->errorFlag = 1;
           break;
        }

    }

};

#endif	/* _UDP_PARSER_H */

